package com.ygqh.baby.controller.kids;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.QueryInfo;
import com.ygqh.baby.ao.RefundStatus;
import com.ygqh.baby.ao.ResponseEntity;
import com.ygqh.baby.ao.ResultSet;
import com.ygqh.baby.controller.kids.model.*;
import com.ygqh.baby.kids.entity.bo.KidsOrder;
import com.ygqh.baby.kids.entity.bo.KidsOrderDetail;
import com.ygqh.baby.kids.entity.bo.KidsProductExt;
import com.ygqh.baby.model.SkuBasicData;
import com.ygqh.baby.model.wdt.qyb.PushOrderToWdtBatchResult;
import com.ygqh.baby.model.wdt.qyb.WdtQybOrderLstReq;
import com.ygqh.baby.model.wdt.qyb.WdtQybOrderReq;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.wdtqyb.api.WdtQybPushOrderByDetailApi;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 线下店订单
 *
 * @author (guohao)
 * @version V1.0
 * @ClassName: KidsOrderController
 * @date 2018年9月30日 下午2:42:27
 */
@RequestMapping("/admin/kids")
@RestController
public class KidsOrderController extends BaseKidsController {

    private Logger logger = LoggerFactory.getLogger(getClass());
    private final static ExecutorService executorService = Executors.newFixedThreadPool(3);


    @Autowired
    private YgOrderService ygOrderService;
    @Autowired
    private KidsOrderLogisticsService kidsOrderLogisticsService;
    @Autowired
    private WdtQybPushOrderByDetailApi pushOrderToWdtByDetailHandler;
    @Autowired
    private YgReturnOrderService ygReturnOrderService;
    @Autowired
    private YgOrderDetailService ygOrderDetailService;
    @Autowired
    private YgProductService ygProductService;
    @Autowired
    private YgSupplierService ygSupplierService;
    @Autowired
    private YgReturnLogService ygReturnLogService;
    @Autowired
    private AdminSkuService adminSkuService;

    /**
     * 保存新世界订单
     *
     * @return ResponseEntity    返回类型
     * @throws
     * @Title: saveOrder
     * @author （guohao）
     * @date 2018年9月30日 下午2:44:06
     * @version V1.0
     */
    @Transactional(rollbackFor = Exception.class)
    @RequestMapping("/saveOrder")
    @ResponseBody
    public ResponseEntity saveOrder(HttpServletRequest request) {
        ResponseEntity validToken = validToken(request);
        if (!validToken.isSuccess()) {
            return validToken;
        }

        String requestPostStr = getRequestPostStr(request);
        logger.info("收到线下店推送订单信息。【{}】", requestPostStr);
        if (StringUtil.isBlank(requestPostStr)) {
            return ResponseEntity.success();
        }
        List<KidsOrderInfo> orderList = JSONObject.parseObject(requestPostStr, new TypeReference<List<KidsOrderInfo>>() {
        });
        String[] orderCodes = orderList.stream().map(KidsOrderInfo::getOutOrderCode).toArray(String[]::new);
        List<YgOrder> ygOrderList = new ArrayList<>();
        Long[] orderIds = (Long[]) ConvertUtils.convert(orderCodes, Long.class);
        List<Long> exitOrderIds = ygOrderService.findExitOrderIds(Arrays.asList(orderIds));
        order:
        for (KidsOrderInfo info : orderList) {
            KidsOrder order = info.getOrder();
            order.setOrderCode(info.getOutOrderCode());
            if (exitOrderIds.contains(Long.parseLong(order.getOrderCode()))) {
                logger.info("推送订单信息 重复推送。订单编号： {}, 详细信息： {}", order.getPlatformName(), JSON.toJSONString(info));
                continue;
            }
            List<KidsOrderDetail> detailList = info.getDetailList();
            if (CollectionUtils.isEmpty(detailList)) {
                logger.error("推送订单信息异常  订单信息缺失。订单编号： {}, 详细信息： {}", order.getOrderCode(), JSON.toJSONString(info));
                continue;
            }
            String[] skuCodes = detailList.stream().map(KidsOrderDetail::getSkuCode).distinct().toArray(String[]::new);
            List<SkuBasicData> skuList = getBasicDataBySkuCode(skuCodes);
            Map<String, List<SkuBasicData>> collect = skuList.stream().collect(Collectors.groupingBy(SkuBasicData::getSkuCode));
            if (collect.size() < skuCodes.length) {
                logger.error("商品skuCode与m站不一致,订单推送失败。orderCode:{}, 线下店SKU编码：{}", order.getOrderCode(), StringUtil.join(skuCodes, ",".charAt(0)));
                continue;
            }

            Long supplierId = skuList.get(0).getSupplierId();
            order.setSupplierId(supplierId);
            //设置用户
            order.setUserId(40L);
            for (KidsOrderDetail kidsOrderDetail : detailList) {
                kidsOrderDetail.setOrderCode(info.getOutOrderCode());

                List<SkuBasicData> list = collect.get(kidsOrderDetail.getSkuCode());
                if (CollectionUtils.isEmpty(skuList)) {
                    logger.error("壹果系统中不存在 skuCodes = {} 的商品 , 订单编号为： {}", kidsOrderDetail.getSkuCode(), order.getOrderCode());
                    break order;
                }
                SkuBasicData sku = list.get(0);
                kidsOrderDetail.setSupplierId(sku.getSupplierId());
                kidsOrderDetail.setSkuCode(sku.getSkuCode());
                kidsOrderDetail.setSkuId(sku.getSkuId());
            }

            YgOrder ygOrder = new YgOrderBuilder(order, detailList).builder();
            ygOrderList.add(ygOrder);

        }
        ygOrderService.saveOrderList(ygOrderList);

        pushOrderList(ygOrderList);


        return ResponseEntity.success();
    }

    private void pushOrderList(List<YgOrder> ygOrderList) {
        executorService.execute(() -> {
            try {
                ResponseEntity responseEntity = pushOrderToWdtByDetailHandler.pushOrderToWdtBatch(null, ygOrderList);
                if (responseEntity.isSuccess()) {
                    PushOrderToWdtBatchResult result = (PushOrderToWdtBatchResult) responseEntity.getData();
                    ygOrderService.updateWdtCodeBatch(result.getSuccessList());
                }
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("推送订单到旺店通失败。订单信息：{}", JSON.toJSONString(ygOrderList));
            }
        });

    }

    @RequestMapping("/searchOrderLogistics")
    @ResponseBody
    public ResponseEntity searchOrderLogistics(QueryInfo queryInfo, String orderCode, HttpServletRequest request) {
        ResponseEntity validToken = validToken(request);
        if (!validToken.isSuccess()) {
            return validToken;
        }
        if (queryInfo.getLimit() == 0) {
            queryInfo.setLimit(100);
        }
        ResultSet<KidsOrderLogistics> search = kidsOrderLogisticsService.search(queryInfo, orderCode, false);
        return ResponseEntity.success(search);
    }

    @RequestMapping("/orderLogisticsBack")
    @ResponseBody
    public ResponseEntity orderLogisticsBack(String idList, HttpServletRequest request) {
        ResponseEntity validToken = validToken(request);
        if (!validToken.isSuccess()) {
            return validToken;
        }
        logger.info("物流推送回调：idList : {}", idList);
        List<Long> orderList = JSONObject.parseObject(idList, new TypeReference<List<Long>>() {
        });
        int updateSyncSuccess = kidsOrderLogisticsService.updateSyncSuccessById(orderList);
        return ResponseEntity.success(updateSyncSuccess);
    }


    @Transactional(rollbackFor = Exception.class)
    @RequestMapping("/saveChangeOrder")
    @ResponseBody
    public ResponseEntity saveChangeOrder(HttpServletRequest request) {
        ResponseEntity validToken = validToken(request);
        if (!validToken.isSuccess()) {
            return validToken;
        }
        String requestPostStr = getRequestPostStr(request);
        logger.info("收到线下店推送换货单信息。【{}】", requestPostStr);
        if (StringUtil.isBlank(requestPostStr)) {
            return ResponseEntity.success();
        }

        List<KidsChangeOrderInfo> changeOrderInfoList =
                JSONObject.parseObject(requestPostStr, new TypeReference<List<KidsChangeOrderInfo>>() {
        });
        List<String> returnCodeList = changeOrderInfoList.stream().map(KidsChangeOrderInfo::getOutCode).
                collect(Collectors.toList());
        List<String> existsReturnCodeList = ygReturnOrderService.findExistsReturnCode(returnCodeList);
        List<YgReturnOrder> returnOrderList = new ArrayList<>(changeOrderInfoList.size());
        List<Long> orderDetailIdList = new ArrayList<>();
        for (KidsChangeOrderInfo changeOrderInfo : changeOrderInfoList) {
            KidsReturnOrder returnOrder = changeOrderInfo.getReturnOrder();
            returnOrder.setReturnCode(changeOrderInfo.getOutCode());
            returnOrder.setOrderCode(changeOrderInfo.getOutOrderCode());

            if (existsReturnCodeList.contains(returnOrder.getReturnCode())) {
                logger.info("推送换货单信息 重复推送。订单编号： {}, 详细信息： {}", returnOrder.getReturnCode(),
                        JSON.toJSONString(changeOrderInfo));
                continue;
            }
            List<KidsReturnOrderDetail> returnOrderDetailList = changeOrderInfo.getReturnOrderDetailList();
            if (CollectionUtils.isEmpty(returnOrderDetailList)) {
                logger.error("推送换货单信息异常  换货单信息缺失。换货单号： {}, 详细信息： {}",
                        returnOrder.getReturnCode(), JSON.toJSONString(changeOrderInfo));
                continue;
            }
            String[] skuCodes = returnOrderDetailList.stream().map(KidsReturnOrderDetail::getSkuCode).toArray(String[]::new);
            List<SkuBasicData> skuList = getBasicDataBySkuCode(skuCodes);
            Map<String, List<SkuBasicData>> collect = skuList.stream().collect(Collectors.groupingBy(SkuBasicData::getSkuCode));
            if (collect.size() < skuCodes.length) {
                logger.error("商品skuCode与m站不一致,换货单推送失败。 线下店SKU编码：{}", StringUtil.join(skuCodes, ",".charAt(0)));
                continue;
            }
            Long supplierId = skuList.get(0).getSupplierId();
            returnOrder.setSupplierId(supplierId);
            returnOrder.setUserId(40L);
            for (KidsReturnOrderDetail returnOrderDetail : returnOrderDetailList) {
                returnOrderDetail.setReturnCode(changeOrderInfo.getOutCode());

                SkuBasicData sku = collect.get(returnOrderDetail.getSkuCode()).get(0);
                returnOrderDetail.setSupplierId(sku.getSupplierId());
                returnOrderDetail.setSkuId(sku.getSkuId());
                returnOrderDetail.setSkuCode(sku.getSkuCode());
                returnOrderDetail.setProductId(sku.getProductId());
                returnOrderDetail.setProductCode(sku.getProductCode());
                returnOrderDetail.setProductName(sku.getProductName());
            }
            YgReturnOrderBuilder returnOrderBuilder = new YgReturnOrderBuilder(returnOrder, returnOrderDetailList);
            YgReturnOrder ygReturnOrder = returnOrderBuilder.builder();
            returnOrderList.add(ygReturnOrder);
            orderDetailIdList.addAll(returnOrderBuilder.getOrderDetailIdByRefund());
        }
        ygReturnOrderService.saveReturnOrderList(returnOrderList);

        ygOrderDetailService.updateRefundStatusById(orderDetailIdList, RefundStatus.ApplyRefund);

        pushChangeOrder(returnOrderList);

        return ResponseEntity.success();
    }

    private List<SkuBasicData> getBasicDataBySkuCode(String[] skuCodes) {
        List<KidsProductExt> productInfoBySku = adminSkuService.findProductDataForKids(skuCodes, null);
        if (CollectionUtils.isEmpty(productInfoBySku)) {
            return new ArrayList<>();
        }
        List<SkuBasicData> skuBasicDataList = new ArrayList<>(skuCodes.length);
        productInfoBySku.forEach(p -> p.getSkuList().forEach(s -> {
            SkuBasicData sku  = new SkuBasicData();
            sku.setSkuCode(s.getSkuCode());
            sku.setProductId(p.getYiigooId());
            sku.setSkuId(s.getYiigooId());
            sku.setSupplierId(p.getSupplier().getYiigooId());
            sku.setProductName(p.getProductName());
            sku.setProductCode(p.getProductCode());
            skuBasicDataList.add(sku);
        }));
        return skuBasicDataList;
    }

    private void pushChangeOrder(List<YgReturnOrder> returnOrderList) {
        executorService.execute(() -> {
            List<WdtQybOrderReq> orderList = new ArrayList<>();
            returnOrderList.forEach(returnOrder -> {
                WdtQybOrderReq wdtQybOrderReq = pushChangeOrder(returnOrder);
                if (wdtQybOrderReq != null) {
                    orderList.add(wdtQybOrderReq);
                }
            });
            try {
                ResponseEntity pushChangeResult = pushOrderToWdtByDetailHandler.pushOrderToWdt(null, orderList);
                if (!pushChangeResult.isSuccess()) {
                    logger.error("推送换货单到旺店通失败。推送结果：{}，换货单信息：{}", JSON.toJSONString(pushChangeResult),
                            JSON.toJSONString(returnOrderList));
                } else {
                    List<String> returnCodeList = returnOrderList.stream().map(YgReturnOrder::getReturnCode).collect(Collectors.toList());
                    ygReturnOrderService.updateWdtOrderCode(returnCodeList);
                }
            } catch (Exception e) {
                logger.error("推送换货单到旺店通失败。换货单信息：{}", JSON.toJSONString(returnOrderList));
                e.printStackTrace();
            }
        });
    }

    private WdtQybOrderReq pushChangeOrder(YgReturnOrder changeOrder) {
        Long[] productIds = changeOrder.getReturnOrderDetails().stream().map(YgReturnOrderDetail::getProductId).toArray(Long[]::new);
        List<YgProduct> productList = ygProductService.findByIds(productIds);
        Map<Long, List<YgProduct>> collect = productList.stream().collect(Collectors.groupingBy(YgProduct::getId));
        List<WdtQybOrderLstReq> detailList = new ArrayList<>();
        for (YgReturnOrderDetail rod : changeOrder.getReturnOrderDetails()) {
            if (ygSupplierService.isSyncWDT(rod.getSupplierId())) {
                YgProduct product = collect.get(rod.getProductId()).get(0);
                WdtQybOrderLstReq newLstReq = new WdtQybOrderLstReq(changeOrder.getReturnCode() + "-" + rod.getId(), new BigDecimal(rod.getAmount()),
                        BigDecimal.ZERO, 30, 0, product.getProductCode(), rod.getProductName(), rod.getSkuCode(),
                        product.getShortName() + " " + rod.getSizeName(), "");
                newLstReq.setShareDiscount(BigDecimal.ZERO);
                detailList.add(newLstReq);
            }
        }
        if (org.springframework.util.CollectionUtils.isEmpty(detailList)) {
            ygReturnLogService.addReturnLog(changeOrder.getReturnCode(), changeOrder.getOrderId(), "需要退换的明细为空，不予同步。",
                    "pushChangeOrderBefore", "");
            return null;
        }

        // 订单主信息
        WdtQybOrderReq orderReq = new WdtQybOrderReq(changeOrder.getReturnCode(), 30, 1, "2", changeOrder.getReceiver(), changeOrder.getProvinceName(),
                changeOrder.getCityName(), changeOrder.getAreaName(), changeOrder.getAddress(), "-1", "0", "0", "0",
                "0", "0", detailList);
        orderReq.setReceiverMobile(changeOrder.getTelPhone());
        orderReq.setTradeTime(changeOrder.getCreateTime());
        orderReq.setPayTime(changeOrder.getCreateTime());
        return orderReq;
    }
}
